﻿using AutoMapper;
using IntelligentAgriculture.Contracts.Dto.Input;
using IntelligentAgriculture.Contracts.Dto.Output;
using IntelligentAgriculture.Contracts.Interface.SheepFileModelInterface;
using IntelligentAgriculture.Domain;
using IntelligentAgriculture.Domain.Entity;
using IntelligentAgriculture.Domain.Interface.IColumnManagement;
using IntelligentAgriculture.Domain.Interface.IEarTagReposiotry;
using IntelligentAgriculture.Domain.Interface.Iridgepletype;
using IntelligentAgriculture.Domain.Interface.SheepFileModelInterface;
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.Logging;

namespace IntelligentAgriculture.Services
{
    public class SheepFileModelService : ISheepFileModelService
    {
        private readonly ISheepFileModelRepository _sheepFileModelRepository;
        private readonly IEarTagReposiotry _earTagReposiotry;
        private readonly IridegRepository _ridegRepository;
        private readonly IColumnManRepository _columnManRepository;
        private readonly ILogger<SheepFileModelService> _logger;
        private readonly AgricultureDbContext _context;
        private readonly IMapper _mapper;
        public SheepFileModelService(ISheepFileModelRepository sheepFileModelRepository, IEarTagReposiotry earTagReposiotry, IridegRepository ridegRepository, IColumnManRepository columnManRepository, ILogger<SheepFileModelService> logger, IMapper mapper, AgricultureDbContext context)
        {
            _sheepFileModelRepository = sheepFileModelRepository;
            _earTagReposiotry = earTagReposiotry;
            _ridegRepository = ridegRepository;
            _columnManRepository = columnManRepository;
            _logger = logger;
            _mapper = mapper;
            _context = context;
        }
        /// <summary>
        /// 羊只档案列表
        /// </summary>
        /// <returns></returns>
        public async Task<PageOutput<SheepfilemodelsOutput>> GetSheepfilemodels(SheepfilemodelInput input)
        {
            var entity = (from sheepfilemodel in _context.Sheepfilemodels
                          join eartag in _context.Eartags on sheepfilemodel.EarTag equals eartag.EarTagNumber into eartagJoin
                          from eartag in eartagJoin.DefaultIfEmpty()
                          join ridgepole in _context.Ridgepoles on sheepfilemodel.BuildingId equals ridgepole.RidgepoleId into ridgepoleJoin
                          from ridgepole in ridgepoleJoin.DefaultIfEmpty()
                          join column in _context.Columnmanagements on sheepfilemodel.ColumnId equals column.ColumnManagementId into columnJoin
                          from column in columnJoin.DefaultIfEmpty()
                          select new SheepfilemodelsOutput
                          {
                              EarTag = eartag != null ? eartag.EarTagNumber : null,
                              ElectEarNum = sheepfilemodel.ElectEarNum,
                              SheepFileId = sheepfilemodel.SheepFileId,
                              AblactationDate = sheepfilemodel.AblactationDate,
                              AblactationWeight = sheepfilemodel.AblactationWeight,
                              AdmissionDate = sheepfilemodel.AdmissionDate,
                              BirthContent = sheepfilemodel.BirthContent,
                              BirthDate = sheepfilemodel.BirthDate,
                              BirthPlace = sheepfilemodel.BirthPlace,
                              BirthState = sheepfilemodel.BirthState,
                              BirthWeight = sheepfilemodel.BirthWeight,
                              BuildingId = ridgepole != null ? ridgepole.RidgepoleId : (int?)null,
                              BuildingName = ridgepole != null ? ridgepole.RidgepoleName : null,
                              ColumnId = column != null ? column.ColumnManagementId : (int?)null,
                              ColumnName = column != null ? column.ColumnName : null,
                              GeneticGrade = sheepfilemodel.GeneticGrade,
                              Growthstage = sheepfilemodel.Growthstage,
                              IsPregnancy = sheepfilemodel.IsPregnancy,
                              MatherEarNum = sheepfilemodel.MatherEarNum,
                              PrantEarNum = sheepfilemodel.PrantEarNum,
                              PresentState = sheepfilemodel.PresentState,
                              ProduceLevel = sheepfilemodel.ProduceLevel,
                              ReproductionState = sheepfilemodel.ReproductionState,
                              ReproductionStateNum = sheepfilemodel.ReproductionStateNum,
                              SaleLevel = sheepfilemodel.SaleLevel,
                              SheepSex = sheepfilemodel.SheepSex,
                              SheepType = sheepfilemodel.SheepType,
                              Variety = sheepfilemodel.Variety,
                              CreateName = sheepfilemodel.CreateName,
                              CreateTime = sheepfilemodel.CreateTime,
                              UpdateName = sheepfilemodel.UpdateName,
                              UpdateTime = sheepfilemodel.UpdateTime,
                              IsDel = sheepfilemodel.IsDel
                          });

            if (!string.IsNullOrEmpty(input.EarTag))
            {
                entity = entity.Where(c => c.EarTag == input.EarTag);
            }
            if (!string.IsNullOrEmpty(input.ElectEarNum))
            {
                entity = entity.Where(c => c.ElectEarNum == input.ElectEarNum);
            }
            if (input.Variety > 0)
            {
                entity = entity.Where(c => c.Variety == input.Variety);
            }
            if (input.SheepSex != null)
            {
                entity = entity.Where(c => c.SheepSex == input.SheepSex);
            }
            if (!string.IsNullOrEmpty(input.StartDate))
            {
                entity = entity.Where(c => c.BirthDate >= DateTime.Parse(input.StartDate));
            }
            if (!string.IsNullOrEmpty(input.EndDate))
            {
                entity = entity.Where(c => c.BirthDate < DateTime.Parse(input.EndDate).AddDays(1));
            }

            if (input.StartMonthold > 0)
            {
                entity = entity.Where(c => (DateTime.Now.Month - c.BirthDate.Value.Month) >= input.StartMonthold);
            }
            if (input.EndMonthold > 0)
            {
                entity = entity.Where(c => (DateTime.Now.Month - c.BirthDate.Value.Month) <= input.EndMonthold);
            }
            if (input.Growthstage > 0)
            {
                entity = entity.Where(c => c.Growthstage == input.Growthstage);
            }
            if (input.BuildingId > 0)
            {
                entity = entity.Where(c => c.BuildingId == input.BuildingId);
            }
            if (input.ColumnId > 0)
            {
                entity = entity.Where(c => c.ColumnId == input.ColumnId);
            }
            if (input.SheepType > 0)
            {
                entity = entity.Where(c => c.ProduceLevel == input.SheepType);
            }
            if (input.GeneticGrade > 0)
            {
                entity = entity.Where(c => c.GeneticGrade == input.GeneticGrade);
            }
            if (input.ProduceLevel > 0)
            {
                entity = entity.Where(c => c.ProduceLevel == input.ProduceLevel);
            }
            if (input.SaleLevel > 0)
            {
                entity = entity.Where(c => c.SaleLevel == input.SaleLevel);
            }
            if (input.ReproductionState > 0)
            {
                entity = entity.Where(c => c.ReproductionState == input.ReproductionState);
            }

            if (input.StartReproductionStateNum > 0)
            {
                entity = entity.Where(c => c.ReproductionStateNum >= input.StartReproductionStateNum);
            }
            if (input.EndReproductionStateNum > 0)
            {
                entity = entity.Where(c => c.ReproductionStateNum <= input.EndReproductionStateNum);
            }
            if (!string.IsNullOrEmpty(input.PrantEarNum))
            {
                entity = entity.Where(c => c.PrantEarNum == input.PrantEarNum);
            }
            if (!string.IsNullOrEmpty(input.MatherEarNum))
            {
                entity = entity.Where(c => c.MatherEarNum == input.MatherEarNum);
            }
            if (input.PresentState > 0)
            {
                entity = entity.Where(c => c.PresentState == input.PresentState);
            }
            var result = new PageOutput<SheepfilemodelsOutput>
            {
                TotalCount = entity.Count(),
                PageSize = input.PageSize,
            };
            entity = entity.OrderByDescending(c => c.CreateTime).Skip(input.PageSize * (input.PageIndex - 1)).Take(input.PageSize);
            var entities = await entity.ToListAsync();
            result.Data = _mapper.Map<List<SheepfilemodelsOutput>>(entities);
            return result;
        }
        /// <summary>
        /// 档案添加
        /// </summary>
        /// <param name="model"></param>
        /// <returns></returns>
        public async Task<int> AddSheepfilemodel(Sheepfilemodel sheepfile)
        {
            try
            {

                var Elist = await _earTagReposiotry.GetShow();
                var eartag = Elist.FirstOrDefault(c => c.EarTagNumber == sheepfile.EarTag && c.EarTagBreeds == sheepfile.Variety && c.Isdel == false);
                if (eartag == null)
                {
                    return -1; //该品种不存在输入耳号
                }
                //if(eartag.EarTagBirthStatus!= sheepfile.BirthState)
                //{
                //    return -2;//该耳号适配的羊只的出生状态不正确
                //}
                if (eartag.EarTagUseStatus == 1)
                {
                    return -2;//该耳号已被使用
                }
                //将耳标状态设为已使用
                eartag.EarTagUseStatus = 1;
                eartag.EarTagInHouseDate = DateTime.Now;
                var ear = await _earTagReposiotry.UpdateAsync(eartag);
                if (ear == null)
                {
                    return 0;//添加失败
                }
                var list = _mapper.Map<Sheepfilemodel>(sheepfile);
                list.IsPregnancy = 0;
                list.PresentState = 1;
                list.ReproductionState = (list.SheepType == 1) ? 1 : 0;
                list.AblactationDate = null;
                list.CreateTime = DateTime.Now;
                list.UpdateTime = DateTime.Now;
                list.IsDel = false;
                var entity = await _sheepFileModelRepository.AddSheepFileModel(list);
                if (entity != null)
                {
                    return 1;//添加成功
                }
                return -3;//添加失败  
            }
            catch (Exception)
            {

                throw;

            }
        }
        /// <summary>
        /// 档案删除
        /// </summary>
        /// <param name="sheepfileId"></param>
        /// <returns></returns>
        public async Task<int> DeleteSheepFileModel(int sheepfileId)
        {
            return await _sheepFileModelRepository.DeleteSheepFileModel(sheepfileId);
        }
        /// <summary>
        /// 档案反填
        /// </summary>
        /// <param name="sheepfileId"></param>
        /// <returns></returns>
        public async Task<SheepfileInfo> ListSheepfilemodel(int sheepfileId)
        {
            // 从仓储中获取羊档案实体
            var entity = await _sheepFileModelRepository.ListSheepFileModel(sheepfileId);

            // 计算一些派生属性
            int? ablactationDayold = entity.AblactationDate.HasValue ? (DateTime.Now.Day - entity.AblactationDate.Value.Day) : (int?)0;
            int sheepfileDayold = (int)(DateTime.Now - entity.BirthDate.Value).TotalDays;
            int sheepfileMonthold = DateTime.Now.Month - entity.BirthDate.Value.Month;

            // 查询数据并映射为 SheepfileInfo 对象
            var query = (from sheepfilemodel in _context.Sheepfilemodels
                         where sheepfilemodel.SheepFileId == sheepfileId
                         join eartag in _context.Eartags on sheepfilemodel.EarTag equals eartag.EarTagNumber into eartagJoin
                         from eartag in eartagJoin.DefaultIfEmpty()
                         join ridgepole in _context.Ridgepoles on sheepfilemodel.BuildingId equals ridgepole.RidgepoleId into ridgepoleJoin
                         from ridgepole in ridgepoleJoin.DefaultIfEmpty()
                         join column in _context.Columnmanagements on sheepfilemodel.ColumnId equals column.ColumnManagementId into columnJoin
                         from column in columnJoin.DefaultIfEmpty()
                         select new SheepfileInfo
                         {
                             SheepFileId = sheepfilemodel.SheepFileId,
                             EarTag = sheepfilemodel.EarTag,
                             Variety = sheepfilemodel.Variety,
                             ElectEarNum = sheepfilemodel.ElectEarNum,
                             ColumnId = sheepfilemodel.ColumnId,
                             AblactationDate = sheepfilemodel.AblactationDate,
                             AblactationWeight = sheepfilemodel.AblactationWeight,
                             BirthDate = sheepfilemodel.BirthDate,
                             BirthPlace = sheepfilemodel.BirthPlace,
                             BirthWeight = sheepfilemodel.BirthWeight,
                             BuildingId = sheepfilemodel.BuildingId,
                             MatherEarNum = sheepfilemodel.MatherEarNum,
                             PrantEarNum = sheepfilemodel.PrantEarNum,
                             GeneticGrade = sheepfilemodel.GeneticGrade,
                             ProduceLevel = sheepfilemodel.ProduceLevel,
                             ReproductionState = sheepfilemodel.ReproductionState,
                             SheepSex = sheepfilemodel.SheepSex,
                             SaleLevel = sheepfilemodel.SaleLevel,
                             CreateName = sheepfilemodel.CreateName,
                             CreateTime = sheepfilemodel.CreateTime,
                             UpdateName = sheepfilemodel.UpdateName,
                             UpdateTime = sheepfilemodel.UpdateTime,
                             PresentState = sheepfilemodel.PresentState,
                             IsPregnancy = sheepfilemodel.IsPregnancy,
                             BuildingName = ridgepole.RidgepoleName,
                             ColumnName = column.ColumnName,
                             ReproductionStateNum = sheepfilemodel.ReproductionStateNum,

                             AblactationDayold = ablactationDayold,
                             SamechildNumber = 0, // 根据业务逻辑设置
                             SheepfileDayold = sheepfileDayold,
                             SheepfileMonthold = sheepfileMonthold,
                             NewParity = 0, // 根据业务逻辑设置
                             SumParity = 0 // 根据业务逻辑设置
                         }).FirstOrDefault(); // 使用FirstOrDefault()获取单个对象

            return query;
        }
        /// <summary>
        /// 档案修改
        /// </summary>
        /// <param name="input"></param>
        /// <returns></returns>
        public async Task<int> UpdaSheepfilemodel(UpdaSheepfileModelInput input)
        {
            var list = _mapper.Map<Sheepfilemodel>(input);
            return await _sheepFileModelRepository.UpdaSheepFileModel(list);

        }
        /// <summary>
        /// 获取父和母的父母辈
        /// </summary>
        /// <param name="Queryable"></param>
        /// <param name="Ear"></param>
        /// <param name="level"></param>
        /// <returns></returns>
        public async Task<List<string>> GetEarTag(IQueryable<Sheepfilemodel> Queryable, string eartag, int level)
        {

            var sheepFile = Queryable.Any(x => x.EarTag == eartag) ? Queryable.FirstOrDefault(c => c.EarTag == eartag) : null;
            List<string> array = new List<string>();
            int count = 0;
            if (level < 4)
            {
                if (sheepFile != null)
                {
                    array.Add(sheepFile.EarTag);
                    if (!string.IsNullOrEmpty(sheepFile.PrantEarNum))
                    {
                        var addArray = await GetEarTag(Queryable, sheepFile.PrantEarNum, level + 1);
                        if (addArray != null)
                        {
                            foreach (var item in addArray)
                            {
                                array.Add(item);
                            }
                        }
                    }
                    else
                    {
                        count = level == 1 ? 3 : level == 2 ? 1 : 0;
                        for (int i = 0; i < count; i++)
                        {
                            array.Add("无");
                        }
                    }
                    if (!string.IsNullOrEmpty(sheepFile.MatherEarNum))
                    {
                        var addArray = await GetEarTag(Queryable, sheepFile.MatherEarNum, level + 1);
                        foreach (var item in addArray)
                        {
                            array.Add(item);
                        }
                    }
                    else
                    {
                        count = level == 1 ? 3 : level == 2 ? 1 : 0;
                        for (int i = 0; i < count; i++)
                        {
                            array.Add("无");
                        }
                    }
                    return array;
                }
                array.Add(eartag);
                count = level == 1 ? 6 : level == 2 ? 2 : 1;
                for (int i = 0; i < count; i++)
                {
                    array.Add("无");
                }
                return array;
            }
            return null;
        }
        /// <summary>
        /// 获取3代关系表
        /// </summary>
        /// <param name="sId">主键</param>
        /// <returns>返回三代关系表</returns>
        public async Task<List<string>> GetGenealogy(int sheepfileId)
        {
            //获取羊只信息
            var Queryable = await _sheepFileModelRepository.GetSheepfilemodels();
            var SheepFile = Queryable.FirstOrDefault(c => c.SheepFileId == sheepfileId);
            List<string> array = new List<string>();
            if (SheepFile.EarTag != null)
            {
                array.Add(SheepFile.EarTag);
                if (!string.IsNullOrEmpty(SheepFile.PrantEarNum))
                {
                    //遍历父耳标
                    var list = await GetEarTag(Queryable, SheepFile.PrantEarNum, 1);
                    foreach (var item in list)
                    {
                        array.Add(item);
                    }
                }
                else
                {
                    for (var i = 0; i < 7; i++)
                    {
                        array.Add("无");
                    }
                }
                if (!string.IsNullOrEmpty(SheepFile.MatherEarNum))
                {
                    //遍历父耳标
                    var list = await GetEarTag(Queryable, SheepFile.MatherEarNum, 1);
                    foreach (var item in list)
                    {
                        array.Add(item);
                    }
                }
                else
                {
                    for (var i = 0; i < 7; i++)
                    {
                        array.Add("无");
                    }
                }
                return array;
            }
            return array;
        }
        /// <summary>
        /// 判断羊只档案耳号
        /// </summary>
        /// <param name="presentState"></param>
        /// <param name="sheepType"></param>
        /// <returns></returns>
        public async Task<IQueryable<Sheepfilemodel>> IsSexSheepfilemodel(int presentState, int sheepType)
        {
            var list = await _sheepFileModelRepository.GetSheepfilemodels();
            if (presentState != 0)
            {
                list = list.Where(c => c.PresentState == presentState);
            }
            if (sheepType != 0)
            {
                list = list.Where(c => c.SheepType == sheepType);
            }
            return list;
        }
        /// <summary>
        /// 根据耳号反填养只档案
        /// </summary>
        /// <param name="id"></param>
        /// <returns></returns>
        public Task<Sheepfilemodel> DteilSheepfilemodel(string eartag)
        {
            try
            {
                var result = _sheepFileModelRepository.DteilSheepfilemodel(eartag);
                return result;
            }
            catch (Exception ex)
            {
                _logger.LogError("反填羔羊断奶异常:" + ex.Message);
                throw;
            }
        }
        /// <summary>
        /// 根据生长阶段和在场状态获取耳号
        /// </summary>
        /// <param name="presentState"></param>
        /// <param name="sheepType"></param>
        /// <param name="growthstage"></param>
        /// <returns></returns>

        public async Task<IQueryable<Sheepfilemodel>> GrothSheepfilemodel(int presentState, int sheepType, int growthstage)
        {
            try
            {
                var list = await _sheepFileModelRepository.GetSheepfilemodels();
                if (presentState != 0)
                {
                    list = list.Where(c => c.PresentState == presentState);
                }
                if (sheepType != 0)
                {
                    list = list.Where(c => c.SheepType == sheepType);
                }
                if (growthstage != 0)
                {
                    list = list.Where(c => c.Growthstage == growthstage);
                }
                return list;
            }
            catch (Exception ex)
            {
                _logger.LogError("根据生长阶段和在场状态获取耳号异常:" + ex.Message);
                throw;
            }
        }



        /// <summary>
        /// 根据繁殖状态和在场状态获取耳号
        /// </summary>
        /// <param name="presentState">在场状态</param>
        /// <param name="sheepType">羊只类型</param>
        /// <param name="reproductionState">繁殖状态</param>
        /// <returns>返回数据</returns>

        public async Task<IQueryable<Sheepfilemodel>> GetReproductionState(int presentState, int sheepType)
        {
            try
            {
                var list = await _sheepFileModelRepository.GetSheepfilemodels();
                if (presentState != 0)
                {
                    list = list.Where(c => c.PresentState == presentState);
                }
                if (sheepType != 0)
                {
                    list = list.Where(c => c.SheepType == sheepType);
                }
                //小于6为空怀
                list = list.Where(c => c.ReproductionState <= 6);
                return list;
            }
            catch (Exception ex)
            {
                _logger.LogError("根据繁殖状态和在场状态获取耳号异常:" + ex.Message);
                throw;
            }
        }




    }
}

